package cn.moon.server;


import cn.moon.server.handler.HttpHandler;
import cn.moon.utils.NetworkUtils;
import cn.moon.utils.TableUtils;
import com.beust.jcommander.JCommander;
import com.beust.jcommander.Parameter;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpServerCodec;
import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.ExecutionException;


@Slf4j
public class ProxyServer {

    @Parameter(names = "-bridge", description = "桥端口")
    private static int bridgePort = 0;

    @Parameter(names = "-management", description = "管理端口")
    private static int managementPort = 8000;

    private final NioEventLoopGroup bossGroup = new NioEventLoopGroup();
    private final NioEventLoopGroup workerGroup = new NioEventLoopGroup();

	public void startup() {

        ServerBootstrap management = new ServerBootstrap();

        management.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class)
                .option(ChannelOption.AUTO_READ, true)
                .childHandler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    public void initChannel(SocketChannel ch) {
                        ch.pipeline().addLast(new HttpServerCodec());
                        ch.pipeline().addLast(new HttpObjectAggregator(1024 * 64));
                        ch.pipeline().addLast(new HttpHandler());
                    }
                });

        while (true){
            try{
                management.bind(managementPort).get();
                break;
            }catch (ExecutionException | InterruptedException e){
                managementPort++;
            }
        }

        if(bridgePort != 0){
            HttpHandler.startup(bridgePort);
        }

        TableUtils table = new TableUtils();

        table.addRow("NPXY management is running");
        table.addRow("Local:   " + "http://localhost:" + managementPort);
        table.addRow("Network: " + "http://" + NetworkUtils.findFirstNonLoopbackAddress() + ":" + managementPort);

        System.out.println(table);

	}


    public static void main(String[] args) {

	    ProxyServer proxyServer = new ProxyServer();

        JCommander.newBuilder().addObject(proxyServer).build().parse(args);

        proxyServer.startup();

    }

}
